import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

//Toast 显示位置控制 
enum ToastPostion {
  top,
  center,
  bottom,
}

class Toast {
  // toast靠它加到屏幕上
  static OverlayEntry? _overlayEntry;
  // toast是否正在showing
  static bool _showing = false;
  // 开启一个新toast的当前时间，用于对比是否已经展示了足够时间
  final DateTime startedTime;
  // 提示内容
  final String msg;
  // toast显示时间
  final int showTime;
  // 背景颜色
  final Color bgColor;
  // 文本颜色
  final Color textColor;
  // 文字大小
  final double textSize;
  // 显示位置
  final ToastPostion toastPosition;
  // 左右边距
  final double pdHorizontal;
  // 上下边距
  final double pdVertical;
  Toast(
      BuildContext context, {
        //显示的文本
        this.msg = '',
        //显示的时间 单位毫秒
        this.showTime = 1000,
        //显示的背景
        this.bgColor = Colors.black,
        //显示的文本颜色
        this.textColor = Colors.white,
        //显示的文字大小
        this.textSize = 14.0,
        //显示的位置
        this.toastPosition= ToastPostion.center,
        //文字水平方向的内边距
        this.pdHorizontal = 20.0,
        //文字垂直方向的内边距
        this.pdVertical = 10.0,
      }): startedTime = DateTime.now() {
    //获取OverlayState
    OverlayState overlayState = Overlay.of(context);
    _showing = true;
    if (_overlayEntry == null) {
      //OverlayEntry负责构建布局
      //通过OverlayEntry将构建的布局插入到整个布局的最上层
      _overlayEntry = OverlayEntry(
          builder: (BuildContext context) => Positioned(
            //top值，可以改变这个值来改变toast在屏幕中的位置
            child: Container(
                width: MediaQuery.of(context).size.width,
                height: MediaQuery.of(context).size.height,
                color: Colors.transparent,
                child: Padding(
                  padding: EdgeInsets.symmetric(horizontal: 40.0),
                  child: AnimatedOpacity(
                    opacity: _showing ? 1.0 : 0.0, //目标透明度
                    duration: _showing
                        ? Duration(milliseconds: 100)
                        : Duration(milliseconds: 400),
                    child: _buildToastWidget(),
                  ),
                )),
          ));
      //插入到整个布局的最上层
      overlayState.insert(_overlayEntry!);
    } else {
      //重新绘制UI，类似setState
      _overlayEntry!.markNeedsBuild();
    }

  }


  show() async {
    // 等待时间
    await Future.delayed(Duration(milliseconds: this.showTime));
    //2秒后 到底消失不消失
    if (DateTime.now().difference(this.startedTime).inMilliseconds >= this.showTime) {
      _showing = false;
      _overlayEntry?.markNeedsBuild();
      await Future.delayed(const Duration(milliseconds: 400));
      _overlayEntry?.remove();
      _overlayEntry = null;
    }
  }

  //toast绘制
  _buildToastWidget() {
    return Center(
      child: Card(
        color: bgColor,
        child: Padding(
          padding: EdgeInsets.symmetric(
              horizontal: pdHorizontal, vertical: pdVertical),
          child: Text(
            msg,
            style: TextStyle(
              fontSize: textSize,
              color: textColor,
            ),
          ),
        ),
      ),
    );
  }

//  设置toast位置
  buildToastPosition(context) {
    var backResult;
    if (toastPosition == ToastPostion.top) {
      backResult = MediaQuery.of(context).size.height * 1 / 4;
    } else if (toastPosition == ToastPostion.center) {
      backResult = MediaQuery.of(context).size.height * 2 / 5;
    } else {
      backResult = MediaQuery.of(context).size.height * 3 / 4;
    }
    return backResult;
  }
}



class CustomToast extends StatefulWidget {
  final String message;
  final VoidCallback? onDismiss;

  const CustomToast({
    Key? key,
    required this.message,
    this.onDismiss,
  }) : super(key: key);

  @override
  State<CustomToast> createState() => _CustomToastState();
}

class _CustomToastState extends State<CustomToast> with SingleTickerProviderStateMixin {
  late AnimationController _animationController;
  late Animation<double> _fadeAnimation;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 300),
    );

    _fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
      CurvedAnimation(parent: _animationController, curve: Curves.easeIn),
    );

    _animationController.forward();

    Future.delayed(const Duration(seconds: 2), () {
      _animationController.reverse().then((_) {
        widget.onDismiss?.call();
      });
    });
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return FadeTransition(
      opacity: _fadeAnimation,
      child: Material(
        color: Colors.transparent,
        child: Container(
          // 使用全屏容器来拦截点击事件
          width: MediaQuery.of(context).size.width,
          height: MediaQuery.of(context).size.height,
          color: Colors.transparent,
          child: Center(
            child: Container(
              margin: const EdgeInsets.symmetric(horizontal: 40),
              padding: const EdgeInsets.symmetric(
                horizontal: 24.0,
                vertical: 12.0,
              ),
              decoration: BoxDecoration(
                color: Colors.black.withOpacity(0.7),
                borderRadius: BorderRadius.circular(8.0),
              ),
              child: Text(
                widget.message,
                style: const TextStyle(
                  color: Colors.white,
                  fontSize: 16.0,
                ),
                textAlign: TextAlign.center,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

class ToastManager {
  static OverlayEntry? _overlayEntry;

  static void show(BuildContext context, String message) {
    _overlayEntry?.remove();
    _overlayEntry = null;

    _overlayEntry = OverlayEntry(
      builder: (context) => CustomToast(
        message: message,
        onDismiss: () {
          _overlayEntry?.remove();
          _overlayEntry = null;
        },
      ),
    );

    Overlay.of(context).insert(_overlayEntry!);
  }

  static void dismiss() {
    _overlayEntry?.remove();
    _overlayEntry = null;
  }
}

